package service

import (
	"errors"

	"gitee.com/sansaniot/ssiot-core/facade/env"
	"gitee.com/sansaniot/ssiot-core/httpmvc/service"
	"github.com/bytedance/sonic"
	"gorm.io/gorm"

	"ssalarm/common/constant"
	"ssalarm/common/dto"
	"ssalarm/internal/alarm/models"
	"ssalarm/internal/alarm/models/command"
	"ssalarm/internal/alarm/models/query"
)

type AlarmConfig struct {
	sysDevModel    *models.SysDev
	sysAlarmConfig *models.SysAlarmConfig
	service.Service
}

func (d *AlarmConfig) SetDevModel(m *models.SysDev) *AlarmConfig {
	d.sysDevModel = m
	return d
}

func (d *AlarmConfig) SetAlarmConfigModel(m *models.SysAlarmConfig) *AlarmConfig {
	d.sysAlarmConfig = m
	return d
}

// 添加编辑告警配置
func (d *AlarmConfig) UpsertAlarmConfig(req *command.AlarmConfigUpsertReq) (err error, alarmConfig models.SysAlarmConfig) {
	if err = d.sysAlarmConfig.FindOne(&alarmConfig, dto.MakeCondition(query.SysAlarmConfigQuery{Sn: req.Sn, Key: req.Key})); err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		return
	}
	if err = req.Generate(&alarmConfig); err != nil {
		return
	}
	if err = d.sysAlarmConfig.Upsert(&alarmConfig, []string{"dev_sn", "key"}...); err != nil {
		return
	}
	if len(req.ProductCode) == 0 {
		// 设备告警配置缓存
		redisWarn := make([]map[string]interface{}, 0)
		GenRedisWarn(&redisWarn, req.Warning)
		bytes, _ := sonic.Marshal(redisWarn)
		redisWarnStr := string(bytes)
		if err = env.Cache.HashSet(constant.AlarmConfigKey+alarmConfig.DevSn, map[string]interface{}{alarmConfig.Key: redisWarnStr}); err == nil {
			constant.HasAlarmConfigSn.Store(alarmConfig.DevSn, alarmConfig.DevSn)
		}
	}
	return
}

// 删除告警配置
func (d *AlarmConfig) DeleteAlarmConfig(req *command.AlarmConfigDeleteReq) (err error) {
	if len(req.Sn) == 0 && len(req.ProductCode) == 0 {
		return errors.New("参数异常sn/productCode")
	}
	cond := dto.MakeCondition(query.SysAlarmConfigQuery{SnEq: req.Sn, ProductCodeEq: req.ProductCode, KeyEq: req.Key})
	configList := make([]models.SysAlarmConfig, 0)
	if err = d.sysAlarmConfig.FindList(&configList, cond); err != nil {
		return
	}
	if err = d.sysAlarmConfig.Delete(d.sysAlarmConfig, cond); err != nil {
		return
	}
	for _, v := range configList {
		if len(v.ProductCode) == 0 {
			if err = env.Cache.HashDel(constant.AlarmConfigKey+v.DevSn, v.Key); err == nil {
				constant.HasAlarmConfigSn.Delete(v.DevSn)
			}
		}
	}
	return
}
